package com.ruoyi.store.service.impl;

import com.ruoyi.common.core.utils.PageUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.store.mapper.StockLossDetailMapper;
import com.ruoyi.store.mapper.StockLossMapper;
import com.ruoyi.store.service.IStockLossService;
import com.ruoyi.system.api.domain.store.StockLoss;
import com.ruoyi.system.api.domain.store.StockLossDetail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 报损单Service业务层处理
 *
 * @author wl
 * @date 2024-11-04
 */
@Service
@Slf4j
public class StockLossServiceImpl implements IStockLossService {
    @Autowired
    private StockLossMapper stockLossMapper;

    @Autowired
    private StockLossDetailMapper stockLossDetailMapper;

    /**
     * 查询报损单
     *
     * @param id 报损单主键
     * @return 报损单
     */
    @Override
    public StockLoss selectStockLossById(Integer id) {
        StockLoss stockLoss = stockLossMapper.selectStockLossById(id);
        List<StockLossDetail> stockLossDetailList = stockLossDetailMapper.selectStockLossDetailByLossId(id);
        stockLoss.setStockLossDetailList(stockLossDetailList);
        return stockLoss;
    }

    /**
     * 查询报损单列表
     *
     * @param stockLoss 报损单
     * @return 报损单
     */
    @Override
    public List<StockLoss> selectStockLossList(StockLoss stockLoss) {
        PageUtils.startPage();
        return stockLossMapper.selectStockLossList(stockLoss);
    }

    /**
     * 新增报损单
     *
     * @param stockLoss 报损单
     * @return 结果
     */
    @Transactional
    public AjaxResult insertStockLoss(StockLoss stockLoss) {
        //校验单据编号
        if (StringUtils.isBlank(stockLoss.getOrderCode())) {
            return AjaxResult.error("单据编号不能为空");
        }

        //校验单据日期
        if (stockLoss.getOrderDate() == null) {
            return AjaxResult.error("单据日期不能为空");
        }

        //校验报损类型
        if (stockLoss.getLossType() == null) {
            return AjaxResult.error("报损类型不能为空");
        }

        //根据类型校验源单号
        if (stockLoss.getLossType() != 2 && StringUtils.isBlank(stockLoss.getSrcOrderCode())) {
            return AjaxResult.error("源单号不能为空");
        }

        int lossTotal = 0;
        BigDecimal lossPrice = BigDecimal.ZERO;
        //获取明细，计算总数跟总价
        List<StockLossDetail> stockLossDetailList = stockLoss.getStockLossDetailList();
        //校验明细
        if (stockLossDetailList == null || stockLossDetailList.isEmpty()) {
            return AjaxResult.error("明细不能为空");
        }
        for (StockLossDetail stockLossDetail : stockLossDetailList) {
            //校验明细商品
            if (stockLossDetail.getGoodsId() == null) {
                return AjaxResult.error("明细商品不能为空");
            }
            //校验明细数量
            if (stockLossDetail.getTotal() == null || stockLossDetail.getTotal() <= 0) {
                return AjaxResult.error("明细数量不能为空且必须大于0");
            }
            //校验明细单价
            if (stockLossDetail.getPrice() == null || stockLossDetail.getPrice().compareTo(BigDecimal.ZERO) < 0) {
                return AjaxResult.error("明细单价不能为空且必须大于0");
            }

            lossTotal += stockLossDetail.getTotal();
            lossPrice = lossPrice.add(stockLossDetail.getPrice().multiply(new BigDecimal(stockLossDetail.getTotal())));
        }

        //设置总数总价创建人创建时间未生效未关闭未删除
        stockLoss.setLossTotal(lossTotal);
        stockLoss.setLossPrice(lossPrice);
        stockLoss.setCreateBy(SecurityUtils.getUsername());
        stockLoss.setCreateDate(new Date());
        stockLoss.setIsDel(0);

        //持久化数据库
        int addNum = stockLossMapper.insertStockLoss(stockLoss);
        if (addNum <= 0) {
            return AjaxResult.error("新增报损单失败");
        }

        for (StockLossDetail stockLossDetail : stockLossDetailList) {
            //设置报损单id.创建人创建时间未删除
            stockLossDetail.setStockLossId(stockLoss.getId());
            stockLossDetail.setCreateBy(SecurityUtils.getUsername());
            stockLossDetail.setCreateDate(new Date());
            stockLossDetail.setIsDel(0);

            //持久化数据库
            addNum = stockLossDetailMapper.insertStockLossDetail(stockLossDetail);
            if (addNum <= 0) {
                throw new RuntimeException("新增报损单明细失败");
            }
        }
        return AjaxResult.success();
    }

    /**
     * 修改报损单
     *
     * @param stockLoss 报损单
     * @return 结果
     */
    @Override
    public AjaxResult updateStockLoss(StockLoss stockLoss) {
        //校验报损单id不能为空
        if (stockLoss.getId() == null) {
            return AjaxResult.error("报损单id不能为空");
        }

        int lossTotal = 0;
        BigDecimal lossPrice = BigDecimal.ZERO;
        //获取明细，计算总数跟总价
        List<StockLossDetail> stockLossDetailList = stockLoss.getStockLossDetailList();
        //校验明细
        if (stockLossDetailList == null || stockLossDetailList.isEmpty()) {
            return AjaxResult.error("明细不能为空");
        }
        for (StockLossDetail stockLossDetail : stockLossDetailList) {
            //校验明细商品
            if (stockLossDetail.getGoodsId() == null) {
                return AjaxResult.error("明细商品不能为空");
            }
            //校验明细数量
            if (stockLossDetail.getTotal() == null || stockLossDetail.getTotal() <= 0) {
                return AjaxResult.error("明细数量不能为空且必须大于0");
            }
            //校验明细单价
            if (stockLossDetail.getPrice() == null || stockLossDetail.getPrice().compareTo(BigDecimal.ZERO) < 0) {
                return AjaxResult.error("明细单价不能为空且必须大于0");
            }

            lossTotal += stockLossDetail.getTotal();
            lossPrice = lossPrice.add(stockLossDetail.getPrice().multiply(new BigDecimal(stockLossDetail.getTotal())));
        }

        //删除原有明细
        int delNum = stockLossDetailMapper.deleteStockLossDetailByStockLossId(stockLoss.getId());
        if (delNum <= 0) {
            return AjaxResult.error("删除报损单明细失败");
        }
        //设置总数总价创建人创建时间未生效未关闭未删除
        stockLoss.setLossTotal(lossTotal);
        stockLoss.setLossPrice(lossPrice);
        stockLoss.setModifyBy(SecurityUtils.getUsername());
        stockLoss.setModifyDate(new Date());

        //持久化数据库
        int updNum = stockLossMapper.updateStockLoss(stockLoss);
        log.info("StockLossServiceImpl updateStockLoss updNum:{}", updNum);
        if (updNum <= 0) {
            return AjaxResult.error("修改报损单失败");
        }

        for (StockLossDetail stockLossDetail : stockLossDetailList) {
            //设置报损单id.创建人创建时间未删除
            stockLossDetail.setStockLossId(stockLoss.getId());
            stockLossDetail.setCreateBy(SecurityUtils.getUsername());
            stockLossDetail.setCreateDate(new Date());
            stockLossDetail.setIsDel(0);

            //持久化数据库
            updNum = stockLossDetailMapper.insertStockLossDetail(stockLossDetail);
            log.info("StockLossServiceImpl insertStockLossDetail updNum:{}", updNum);
            if (updNum <= 0) {
                throw new RuntimeException("修改报损单明细失败");
            }
        }

        return AjaxResult.success();
    }

    /**
     * 批量删除报损单
     *
     * @param ids 需要删除的报损单主键
     * @return 结果
     */
    @Override
    public AjaxResult deleteStockLossByIds(Integer[] ids) {
        int delNum = stockLossMapper.deleteStockLossByIds(ids);
        log.info("StockLossServiceImpl deleteStockLossByIds delNum:{}", delNum);
        if (delNum <= 0) {
            return AjaxResult.error("删除报损单失败");
        }
        return AjaxResult.success();
    }

    /**
     * 删除报损单信息
     *
     * @param id 报损单主键
     * @return 结果
     */
    @Override
    public AjaxResult deleteStockLossById(Integer id) {
        int delNum = stockLossMapper.deleteStockLossById(id);
        log.info("StockLossServiceImpl deleteStockLossById delNum:{}", delNum);
        if (delNum <= 0) {
            return AjaxResult.error("删除报损单失败");
        }
        return AjaxResult.success();
    }

    /**
     * @return com.ruoyi.common.core.web.domain.AjaxResult
     * @description 校验单据编号
     * @date 2024/11/4 上午10:33
     * @Param orderCode:
     **/
    public AjaxResult checkOrderCode(String orderCode) {
        //校验单据编号是否为空
        if (StringUtils.isBlank(orderCode)) {
            return AjaxResult.error("单据编号不能为空");
        }
        //校验单据编号是否已存在
        int count = stockLossMapper.selectStockLossCountByOrderCode(orderCode);
        log.info("StockLossServiceImpl checkOrderCode count:{}", count);
        if (count > 1) {
            return AjaxResult.error("单据编号已存在");
        }

        return AjaxResult.success();
    }
}
